﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using aspProject.ServiceContracts;
using aspProject.Dmain.DAL;
using aspProject.Dmain.Domain;
using System.ServiceModel.Activation;

namespace aspProject.ServiceLibrary
{
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class LabelService : ILabelService
    {
        private readonly ILabelTypeRepository labelTypeRepo;
        private IProductRepository productRepo;
        private IUserRepository userRepo;
        private readonly CentricEntities context;
        private LabelType currentLabelTypeHolder;

        public LabelService()
        {
            context = new CentricEntities();
            labelTypeRepo = new LabelTypeRepository(context);
            productRepo = new ProductRepository(context);
            userRepo = new UserRepository(context);
        }

        public LabelService(ILabelTypeRepository labelTypeRepository, IProductRepository productRepository,
                            IUserRepository userRepository)
        {
            this.labelTypeRepo = labelTypeRepository;
            this.productRepo = productRepository;
            this.userRepo = userRepository;
        }

        public IEnumerable<LabelTypeDetail> GetLabelTypes()
        {
            List<LabelTypeDetail> list = new List<LabelTypeDetail>();

            foreach (var labeltype in labelTypeRepo.FindAll().AsEnumerable())
            {

                list.Add(new LabelTypeDetail()
                             {
                                 Id = labeltype.Id,
                                 Name = labeltype.Name
                             });

            }
            return list.AsEnumerable();
        }
    


        public LabelTypeDetail GetLabelTypeDetailById(int id)
        {
            LabelType lt = labelTypeRepo.FindById(id);
            LabelTypeDetail detail = new LabelTypeDetail()
                                         {
                                             Id = lt.Id,
                                             Name = lt.Name
                                         };
            return detail;
        }

        public LabelType GetLabelTypeById(int id)
        {
            return labelTypeRepo.FindById(id);
            
        }


        public IEnumerable<Theme> GetThemes()
        {
            LabelType currentLabelType = labelTypeRepo.FindById(currentLabelTypeHolder.Id);
            return labelTypeRepo.FindAllThemesForType(currentLabelType).AsEnumerable();
        }


        public IEnumerable<DataConfigDetail> GetDataConfigs()
        {
            LabelType currentLabelType = labelTypeRepo.FindById(currentLabelTypeHolder.Id);
            return labelTypeRepo.FindAllDataConfigsForType(currentLabelType).Select(d => new DataConfigDetail() { DataConfigId = d.Id, DataConfigName = d.Name }).AsEnumerable();
        }

        public IEnumerable<FieldConfigDetail> GetFieldConfigs(int labelTypeId)
        {
            LabelType currentLabelType = labelTypeRepo.FindById(labelTypeId);
            return labelTypeRepo.FindAllFieldConfigsForType(currentLabelType).Select(f => new FieldConfigDetail() { FieldConfigId = f.Id, FieldConfigName = f.Name }).AsEnumerable();
        }




        public void SaveToDatabase()
        {
            labelTypeRepo.SaveChanges();
        }


        public IEnumerable<TemplateDetail> GetTemplates()
        {
            //return labelTypeRepo.FindAllTemplatesForType(currentLabelTypeHolder).AsEnumerable();
            //webben nog transformers naar details nodig peisk :(
            return null;
        }

        public void AddDataConfig(DataConfigContract dataConfigContract)
        {
            labelTypeRepo.AddDataConfig(TransformDataConfig(dataConfigContract));
            SaveToDatabase();
        }

        public DataConfigContract GetDataConfig(DataConfigDetail detail)
        {
            //return labelTypeRepo.FindDataConfigById(detail.DataConfigId);
            throw new NotImplementedException();
        }

        public void AddFieldConfig(FieldConfigContract fieldConfigContract)
        {
            labelTypeRepo.AddFieldConfig(TransformFieldConfig(fieldConfigContract));
            SaveToDatabase();
        }

        public FieldConfigContract GetFieldConfig(FieldConfigDetail detail)
        {
            return TransformFieldConfigContract(labelTypeRepo.FindFieldConfigById(detail.FieldConfigId));
         
        }

        public void AddTemplate(TemplateContract templateContract)
        {
            labelTypeRepo.AddTemplate(TransformTemplate(templateContract));
        }

        public TemplateContract GetTemplate(TemplateDetail detail)
        {
         //   return labelTypeRepo.FindTemplateById(detail.TemplateId);
            throw new NotImplementedException();
        }

        private DataConfig TransformDataConfig(DataConfigContract datacon)
        {
            DataConfig nieuw = new DataConfig()
                                   {
                                       Name = datacon.Name,
                                       Databasedata = datacon.Databasedata,
                                   };

            return nieuw;
        }

        private FieldConfig TransformFieldConfig(FieldConfigContract fieldcon)
        {
            FieldConfig nieuw = new FieldConfig()
                                    {
                                        LabelType = currentLabelTypeHolder,
                                        Name = fieldcon.Name,
                                        Components = TransformComponents(fieldcon.Components)
                                  };
            
            return nieuw;
        }

        private ICollection<Component> TransformComponents(ICollection<ComponentContract> components)
        {
            List<Component> nieuwelijst = new List<Component>();
            foreach (var componentContract in components)
            {
                nieuwelijst.Add(TransformComponent(componentContract));
            }
            return nieuwelijst;
        }

        private ICollection<ComponentContract> TransformComponentContracts(ICollection<Component> components )
        {
            List<ComponentContract> nieuwelijst = new List<ComponentContract>();
            foreach (var component in components)
            {
                nieuwelijst.Add(TransformComponentContract(component));
            }
            return nieuwelijst;
        } 

        private Component TransformComponent(ComponentContract componentContract)
        {
            Component nieuw = new Component()
                                  {
                                      fontSize = componentContract.fontSize,
                                      Height = componentContract.Height,
                                      positionLeft = componentContract.positionLeft,
                                      PositionTop = componentContract.positionTop,
                                      Width = componentContract.Width,
                                      text = componentContract.text

                                  };
            return nieuw;

        }

        private ComponentContract TransformComponentContract(Component component)
        {
            ComponentContract nieuw = new ComponentContract()
                                          {
                                              fontSize = component.fontSize,
                                              Height = component.Height,
                                              positionLeft = component.positionLeft,
                                              positionTop = component.PositionTop,
                                              Width = component.Width,
                                              text = component.text
                                              
                                          };
            return nieuw;
        }

        private Template TransformTemplate(TemplateContract templateContract)
        {
            Template nieuw = new Template()
                                 {
                                     DataConfig = TransformDataConfig(templateContract.DataConfig),
                                     FieldConfig = TransformFieldConfig(templateContract.FieldConfig),
                                     LabelType = currentLabelTypeHolder,
                                     Name = templateContract.Name,
                                     Theme = templateContract.Theme
                                 };

            return nieuw;

        }

        private TemplateDetail TransformTemplateDetail(Template temp)
        {
            TemplateDetail nieuw = new TemplateDetail()
                                       {
                                           TemplateId = temp.Id,
                                           TemplateName = temp.Name
                                       };

            return nieuw;

        }

        private DataConfigContract TransformDataConfigContract(DataConfig data)
        {
           DataConfigContract nieuw = new DataConfigContract()
                                           {
                                               Id = data.Id,
                                               Name = data.Name,
                                               Databasedata = data.Databasedata

                                           };
            return nieuw;
        }

        private FieldConfigContract TransformFieldConfigContract(FieldConfig data)
        {
            FieldConfigContract nieuw = new FieldConfigContract()
                                            {
                                                Name = data.Name,
                                                Id = data.Id,
                                                LabelType = new LabelTypeDetail()
                                                                {
                                                                    Id = data.LabelType.Id,
                                                                    Name = data.LabelType.Name
                                                                },
                                                Components = TransformComponentContracts(data.Components)
                                            };
            return nieuw;
        }

    

        public void  SetCurrentLabelType(LabelTypeDetail detail)
             {
                this.currentLabelTypeHolder = GetLabelTypeById(detail.Id);
             }
}   
}
